/************************************************************************

								Heroes IV
					  Copyright 2002, The 3DO Company

	------------------------------------------------------------------
  				foreign_creature_array_window_controls.cpp

 Holds various functions to control what players can do to "foreign" creature arrays
 (creature arrays not owned by the local player). 

	$Header: $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "foreign_creature_array_window_controls.h"

#include "adaptor_handler.h"
#include "adventure_map.h"
#include "creature_array.h"
#include "creature_array_window.h"
#include "creature_stack.h"
#include "drag_creature.h"
#include "function_handler.h"
#include "minimum_maximum.h"

namespace
{
	// ---------------------------------------------------------
	// Decide if a given drag-drop operation is legal between 
	// allies
	// ---------------------------------------------------------
	void validate_allied_drag_drop( t_creature_array_window::t_drag_drop_validate_data const & data, bool & accept, int player_number )
	{
		// Can drag creatures & artifacts -- but not heroes -- in. Cannot drag anything out
		t_drag_creature const * drag_creature = dynamic_cast< t_drag_creature const * >( data.drag_source );

		if ( drag_creature )
		{
			t_creature_array const * source_army = drag_creature->get_source_window()->get_army();

			if ( source_army->get_owner_number() != player_number )
			{
				// Cannot do anything to ally's army
				accept = false;
			}
			else if ( drag_creature->get_source_window() == data.drag_target )
			{
				// Can always rearrange within own army
				accept = true;
			}
			else
			{
				if ( drag_creature->get_data()->get_hero() )
				{
					accept = false;
				}
				else 
				{
					// Don't allow swap-outs
					t_creature_stack const & target_stack = (*data.drag_target->get_army())[data.drag_target_slot];
					
					if ( target_stack.get_number() > 0 && target_stack.get_creature_type() != drag_creature->get_data()->get_creature_type() )
					{
						accept = false;
					}
					else
					{
						accept = true;
					}
				}
			}
		}
		else
		{
			// Bad artifact drags are stopped before this in army dialogs; shouldn't
			// occur anywhere else.
			accept = true;
		}
	}

	// ---------------------------------------------------------
	// Set up allied split operations. Do NOT allow player to pull creatures away
	// from other player's armies
	// ---------------------------------------------------------
	void allied_split_handler( t_creature_array_window::t_split_min_max_data & data, int player_number)
	{
		if ( data.left_army->get_owner_number() != player_number )
		{
			*data.min_left = maximum( 1, (*data.left_army)[data.left_slot].get_number() );
		}

		if ( data.right_army->get_owner_number() != player_number )
		{
			*data.min_right = maximum( 1, (*data.right_army)[data.right_slot].get_number() );
		}
	}
}

// ---------------------------------------------------------
// Set up controls on a creature array window which is 
// dealing with a foreign creature array (either it or
// one of the other creature arrays on the same page has
// a creature array owned by someone else)
// ---------------------------------------------------------
void setup_foreign_creature_array_window_controls( t_adventure_map & map, t_creature_array_window * window )
{
	int player_number = map.get_player_number();

	window->set_drag_validate_handler( add_3rd_argument< int >( function_3_handler( &validate_allied_drag_drop ), player_number ) );
	window->set_split_min_max_handler( add_2nd_argument< int >( function_2_handler( &allied_split_handler ), player_number ) );

	if ( player_number == window->get_army()->get_owner_number() )
	{
		// Some restrictions
		window->set_allow_drags( true );
	}
	else
	{
		// Full restrictions
		window->set_allow_drags( false );
	}
}

// ---------------------------------------------------------
// Clear the controls on a creature array window which were
// set up by setup_foreign_creature_array_window_controls()
// ---------------------------------------------------------
void clear_foreign_creature_array_window_controls( t_creature_array_window * window )
{
	// No restrictions
	window->set_allow_drags( true );
	window->set_drag_validate_handler( t_creature_array_window::t_drag_validate_handler() );
	window->set_split_min_max_handler( t_creature_array_window::t_split_min_max_handler() );
}
